home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / parisc / include / asm / uaccess.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  8.5 KB  |  245 lines

  1. #ifndef __PARISC_UACCESS_H
  2. #define __PARISC_UACCESS_H
  3.  
  4. /*
  5.  * User space memory access functions
  6.  */
  7. #include <asm/page.h>
  8. #include <asm/system.h>
  9. #include <asm/cache.h>
  10. #include <asm-generic/uaccess.h>
  11.  
  12. #define VERIFY_READ 0
  13. #define VERIFY_WRITE 1
  14.  
  15. #define KERNEL_DS    ((mm_segment_t){0})
  16. #define USER_DS     ((mm_segment_t){1})
  17.  
  18. #define segment_eq(a,b)    ((a).seg == (b).seg)
  19.  
  20. #define get_ds()    (KERNEL_DS)
  21. #define get_fs()    (current_thread_info()->addr_limit)
  22. #define set_fs(x)    (current_thread_info()->addr_limit = (x))
  23.  
  24. /*
  25.  * Note that since kernel addresses are in a separate address space on
  26.  * parisc, we don't need to do anything for access_ok().
  27.  * We just let the page fault handler do the right thing. This also means
  28.  * that put_user is the same as __put_user, etc.
  29.  */
  30.  
  31. extern int __get_kernel_bad(void);
  32. extern int __get_user_bad(void);
  33. extern int __put_kernel_bad(void);
  34. extern int __put_user_bad(void);
  35.  
  36. static inline long access_ok(int type, const void __user * addr,
  37.         unsigned long size)
  38. {
  39.     return 1;
  40. }
  41.  
  42. #define put_user __put_user
  43. #define get_user __get_user
  44.  
  45. #if !defined(CONFIG_64BIT)
  46. #define LDD_KERNEL(ptr)        __get_kernel_bad();
  47. #define LDD_USER(ptr)        __get_user_bad();
  48. #define STD_KERNEL(x, ptr)    __put_kernel_asm64(x,ptr)
  49. #define STD_USER(x, ptr)    __put_user_asm64(x,ptr)
  50. #define ASM_WORD_INSN        ".word\t"
  51. #else
  52. #define LDD_KERNEL(ptr)        __get_kernel_asm("ldd",ptr)
  53. #define LDD_USER(ptr)        __get_user_asm("ldd",ptr)
  54. #define STD_KERNEL(x, ptr)    __put_kernel_asm("std",x,ptr)
  55. #define STD_USER(x, ptr)    __put_user_asm("std",x,ptr)
  56. #define ASM_WORD_INSN        ".dword\t"
  57. #endif
  58.  
  59. /*
  60.  * The exception table contains two values: the first is an address
  61.  * for an instruction that is allowed to fault, and the second is
  62.  * the address to the fixup routine. 
  63.  */
  64.  
  65. struct exception_table_entry {
  66.     unsigned long insn;  /* address of insn that is allowed to fault.   */
  67.     long fixup;          /* fixup routine */
  68. };
  69.  
  70. #define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\
  71.     ".section __ex_table,\"aw\"\n"               \
  72.     ASM_WORD_INSN #fault_addr ", " #except_addr "\n\t" \
  73.     ".previous\n"
  74.  
  75. /*
  76.  * The page fault handler stores, in a per-cpu area, the following information
  77.  * if a fixup routine is available.
  78.  */
  79. struct exception_data {
  80.     unsigned long fault_ip;
  81.     unsigned long fault_space;
  82.     unsigned long fault_addr;
  83. };
  84.  
  85. #define __get_user(x,ptr)                               \
  86. ({                                                      \
  87.     register long __gu_err __asm__ ("r8") = 0;      \
  88.     register long __gu_val __asm__ ("r9") = 0;      \
  89.                             \
  90.     if (segment_eq(get_fs(),KERNEL_DS)) {           \
  91.         switch (sizeof(*(ptr))) {                   \
  92.         case 1: __get_kernel_asm("ldb",ptr); break; \
  93.         case 2: __get_kernel_asm("ldh",ptr); break; \
  94.         case 4: __get_kernel_asm("ldw",ptr); break; \
  95.         case 8: LDD_KERNEL(ptr); break;        \
  96.         default: __get_kernel_bad(); break;         \
  97.         }                                           \
  98.     }                                               \
  99.     else {                                          \
  100.         switch (sizeof(*(ptr))) {                   \
  101.         case 1: __get_user_asm("ldb",ptr); break;   \
  102.         case 2: __get_user_asm("ldh",ptr); break;   \
  103.         case 4: __get_user_asm("ldw",ptr); break;   \
  104.         case 8: LDD_USER(ptr);  break;        \
  105.         default: __get_user_bad(); break;           \
  106.         }                                           \
  107.     }                                               \
  108.                             \
  109.     (x) = (__typeof__(*(ptr))) __gu_val;            \
  110.     __gu_err;                                       \
  111. })
  112.  
  113. #define __get_kernel_asm(ldx,ptr)                       \
  114.     __asm__("\n1:\t" ldx "\t0(%2),%0\n\t"        \
  115.         ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_get_user_skip_1)\
  116.         : "=r"(__gu_val), "=r"(__gu_err)        \
  117.         : "r"(ptr), "1"(__gu_err)        \
  118.         : "r1");
  119.  
  120. #define __get_user_asm(ldx,ptr)                         \
  121.     __asm__("\n1:\t" ldx "\t0(%%sr3,%2),%0\n\t"    \
  122.         ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_get_user_skip_1)\
  123.         : "=r"(__gu_val), "=r"(__gu_err)        \
  124.         : "r"(ptr), "1"(__gu_err)        \
  125.         : "r1");
  126.  
  127. #define __put_user(x,ptr)                                       \
  128. ({                                \
  129.     register long __pu_err __asm__ ("r8") = 0;          \
  130.         __typeof__(*(ptr)) __x = (__typeof__(*(ptr)))(x);    \
  131.                                 \
  132.     if (segment_eq(get_fs(),KERNEL_DS)) {                   \
  133.         switch (sizeof(*(ptr))) {                           \
  134.         case 1: __put_kernel_asm("stb",__x,ptr); break;     \
  135.         case 2: __put_kernel_asm("sth",__x,ptr); break;     \
  136.         case 4: __put_kernel_asm("stw",__x,ptr); break;     \
  137.         case 8: STD_KERNEL(__x,ptr); break;            \
  138.         default: __put_kernel_bad(); break;            \
  139.         }                                                   \
  140.     }                                                       \
  141.     else {                                                  \
  142.         switch (sizeof(*(ptr))) {                           \
  143.         case 1: __put_user_asm("stb",__x,ptr); break;       \
  144.         case 2: __put_user_asm("sth",__x,ptr); break;       \
  145.         case 4: __put_user_asm("stw",__x,ptr); break;       \
  146.         case 8: STD_USER(__x,ptr); break;            \
  147.         default: __put_user_bad(); break;            \
  148.         }                                                   \
  149.     }                                                       \
  150.                                 \
  151.     __pu_err;                        \
  152. })
  153.  
  154. /*
  155.  * The "__put_user/kernel_asm()" macros tell gcc they read from memory
  156.  * instead of writing. This is because they do not write to any memory
  157.  * gcc knows about, so there are no aliasing issues. These macros must
  158.  * also be aware that "fixup_put_user_skip_[12]" are executed in the
  159.  * context of the fault, and any registers used there must be listed
  160.  * as clobbers. In this case only "r1" is used by the current routines.
  161.  * r8/r9 are already listed as err/val.
  162.  */
  163.  
  164. #define __put_kernel_asm(stx,x,ptr)                         \
  165.     __asm__ __volatile__ (                              \
  166.         "\n1:\t" stx "\t%2,0(%1)\n\t"            \
  167.         ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_1)\
  168.         : "=r"(__pu_err)                            \
  169.         : "r"(ptr), "r"(x), "0"(__pu_err)        \
  170.             : "r1")
  171.  
  172. #define __put_user_asm(stx,x,ptr)                           \
  173.     __asm__ __volatile__ (                              \
  174.         "\n1:\t" stx "\t%2,0(%%sr3,%1)\n\t"        \
  175.         ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_1)\
  176.         : "=r"(__pu_err)                            \
  177.         : "r"(ptr), "r"(x), "0"(__pu_err)        \
  178.         : "r1")
  179.  
  180.  
  181. #if !defined(CONFIG_64BIT)
  182.  
  183. #define __put_kernel_asm64(__val,ptr) do {            \
  184.     u64 __val64 = (u64)(__val);                \
  185.     u32 hi = (__val64) >> 32;                \
  186.     u32 lo = (__val64) & 0xffffffff;            \
  187.     __asm__ __volatile__ (                    \
  188.         "\n1:\tstw %2,0(%1)"                \
  189.         "\n2:\tstw %3,4(%1)\n\t"            \
  190.         ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_2)\
  191.         ASM_EXCEPTIONTABLE_ENTRY(2b,fixup_put_user_skip_1)\
  192.         : "=r"(__pu_err)                            \
  193.         : "r"(ptr), "r"(hi), "r"(lo), "0"(__pu_err) \
  194.         : "r1");                    \
  195. } while (0)
  196.  
  197. #define __put_user_asm64(__val,ptr) do {                \
  198.     u64 __val64 = (u64)(__val);                \
  199.     u32 hi = (__val64) >> 32;                \
  200.     u32 lo = (__val64) & 0xffffffff;            \
  201.     __asm__ __volatile__ (                    \
  202.         "\n1:\tstw %2,0(%%sr3,%1)"            \
  203.         "\n2:\tstw %3,4(%%sr3,%1)\n\t"            \
  204.         ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_2)\
  205.         ASM_EXCEPTIONTABLE_ENTRY(2b,fixup_put_user_skip_1)\
  206.         : "=r"(__pu_err)                            \
  207.         : "r"(ptr), "r"(hi), "r"(lo), "0"(__pu_err) \
  208.         : "r1");                    \
  209. } while (0)
  210.  
  211. #endif /* !defined(CONFIG_64BIT) */
  212.  
  213.  
  214. /*
  215.  * Complex access routines -- external declarations
  216.  */
  217.  
  218. extern unsigned long lcopy_to_user(void __user *, const void *, unsigned long);
  219. extern unsigned long lcopy_from_user(void *, const void __user *, unsigned long);
  220. extern unsigned long lcopy_in_user(void __user *, const void __user *, unsigned long);
  221. extern long lstrncpy_from_user(char *, const char __user *, long);
  222. extern unsigned lclear_user(void __user *,unsigned long);
  223. extern long lstrnlen_user(const char __user *,long);
  224.  
  225. /*
  226.  * Complex access routines -- macros
  227.  */
  228.  
  229. #define strncpy_from_user lstrncpy_from_user
  230. #define strnlen_user lstrnlen_user
  231. #define strlen_user(str) lstrnlen_user(str, 0x7fffffffL)
  232. #define clear_user lclear_user
  233. #define __clear_user lclear_user
  234.  
  235. unsigned long copy_to_user(void __user *dst, const void *src, unsigned long len);
  236. #define __copy_to_user copy_to_user
  237. unsigned long copy_from_user(void *dst, const void __user *src, unsigned long len);
  238. #define __copy_from_user copy_from_user
  239. unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned long len);
  240. #define __copy_in_user copy_in_user
  241. #define __copy_to_user_inatomic __copy_to_user
  242. #define __copy_from_user_inatomic __copy_from_user
  243.  
  244. #endif /* __PARISC_UACCESS_H */
  245.